<?php
/**
 * 文件上传类 - JBlog
 * 
 * @copyright (c) 2008-2012 JBlog (www.lisijie.org)
 * @author lisijie <lisijie86@gmail.com>
 * @version $Id: Upload.php 17 2012-07-09 07:34:22Z lisijie86@gmail.com $
*/

class Upload {
	
	private $root;
	private $updir;
	private $allowtypes = array();
	private $dirrule = '';
	private $maxsize = 0;
	private $result = array();
	
	public function __construct() {
		$this->root = DATA_PATH;
		$this->updir = 'attach/';
		$this->allowtypes = explode('|',JBlog::config('blog.uploadtype')); //允许上传的文件类型列表
		$this->dirrule = JBlog::config('blog.uploadrule'); //上传目录命名规则
		$this->maxsize = JBlog::config('blog.uploadsize') * 1024; //最大允许上传的文件大小 
		$this->makepath(); //创建目录
	}
	
	/**
	 * 执行上传动作
	 * 
	 * @param string $field 表单项名称
	 * @return array 返回上传结果
	 */
	public function execute($field) {
		@set_time_limit(0);
		$keys = array_keys($_FILES[$field]);
		$_FILES[$field]['name'] = array_unique($_FILES[$field]['name']);
		$nkeys = array_keys($_FILES[$field]['name']);
		$files = array();
		foreach ( $nkeys as $nkey ) {
			if ( !empty($_FILES[$field]['name'][$nkey]) ) {
				$files[$nkey] = array();
				foreach ( $keys as $key ) {
					$files[$nkey][$key] = $_FILES[$field][$key][$nkey];
				}
			}
		}
		unset($nkeys, $keys, $_FILES);
		if ( $files ) {
			$i = -1;
			foreach ( $files as $key => $file ) {
				$i++;
				$fileext = $this->fileext($file['name']);
				$this->result[$i] = array(
					'err' => $file['error'],
					'errmsg' => $this->errmsg($file['error']),
					'name' => $file['name'],
					'path' => '',
					'size' => $file['size'],
					'type' => $file['type'],
					'ext' => $fileext,
				);
				if ( !$file['error'] ) {
					if ( $file['size'] > $this->maxsize ) {
						$this->result[$i]['err'] = -1;
						$this->result[$i]['errmsg'] = $this->errmsg(-1);
						continue;
					}
					if ( !in_array($fileext, $this->allowtypes) ) {
						$this->result[$i]['err'] = -2;
						$this->result[$i]['errmsg'] = $this->errmsg(-2);
						continue;
					}
					$file['tmp_name'] = str_replace('\\\\', '\\', $file['tmp_name']);
					if ( is_uploaded_file($file['tmp_name']) ) {
						$filepath = $this->updir.date('YmdHis').mt_rand(100,999).".{$fileext}";
						if ( move_uploaded_file($file['tmp_name'], $this->root.$filepath) ) {
							$this->result[$i]['path'] = $filepath;
							@unlink($file['tmp_name']);
						}
					}
				}
			}
		}
		return $this->result;
	}
	
	/**
	 * 按照指定规则创建上传目录
	 */
	public function makepath() {
		if ( empty($this->dirrule) ) return ;
		$dir = str_replace(array('{y}','{m}','{d}','\\','.'),array(get_date(NOW,'Y'),get_date(NOW,'m'),get_date(NOW,'d'),'/',''),$this->dirrule);
		$dirs = explode('/', trim($dir, '/'));
		foreach ( $dirs as $d ) {
			$this->updir .= $d.'/';
			if ( !is_dir($this->root.$this->updir) ) {
				@mkdir($this->root.$this->updir);
				@chmod($this->root.$this->updir, 0777);
			}
		}
	}
	
	/**
	 * 根据错误号返回错误消息
	 * 
	 * @param int $err
	 */
	public function errmsg($err) {
		$msg = '';
		switch ($err) {
			case 1: $msg = __('文件超过了 php.ini 中 upload_max_filesize 选项限制的值。'); break;
			case 2: $msg = __('上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。'); break;
			case 3: $msg = __('文件只有部分被上传。'); break;
			case 4: $msg = __('没有文件被上传。'); break;
			case 6: $msg = __('找不到临时文件夹。'); break;
			case 7: $msg = __('文件写入失败。'); break;
			case -1: $msg = __('文件大小超出限制。'); break;
			case -2: $msg = __('文件类型不允许。'); break;
			default: $msg = '未知错误。';
		}
		return $msg;
	}
	
	/**
	 * 返回小写文件扩展名
	 * 
	 * @param string $file 文件名
	 */
	public function fileext($file) {
		return strtolower(pathinfo($file, PATHINFO_EXTENSION));
	}
}
